home *** CD-ROM | disk | FTP | other *** search
- /*
- * Program: Buffer management routines
- *
- * Modifier: Michael Seibel
- * Networks and Distributed Computing
- * Computing & Communications
- * University of Washington
- * Administration Building, AG-44
- * Seattle, WA 98195
- * Internet: mikes@cac.washington.edu
- *
- * Date: 19 Jan 1991
- * Last Edited: 6 Jan 1992
- *
- * Copyright 1991 by the University of Washington
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appears in all copies and that both the
- * above copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the University of Washington not be
- * used in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. This software is made
- * available "as is", and
- * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
- * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
- * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
- * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
- /*
- * Buffer management.
- * Some of the functions are internal,
- * and some are actually attached to user
- * keys. Like everyone else, they set hints
- * for the display system.
- */
- #include <stdio.h>
- #include "estruct.h"
- #include "pico.h"
- #include "edef.h"
-
-
- zotbuf(bp) /* kill the buffer pointed to by bp */
-
- register BUFFER *bp;
-
- {
- register BUFFER *bp1;
- register BUFFER *bp2;
- register int s;
-
- if (bp->b_nwnd != 0) { /* Error if on screen. */
- mlwrite("Buffer is being displayed");
- return (FALSE);
- }
- if ((s=bclear(bp)) != TRUE) /* Blow text away. */
- return (s);
- free((char *) bp->b_linep); /* Release header line. */
- bp1 = NULL; /* Find the header. */
- bp2 = bheadp;
- while (bp2 != bp) {
- bp1 = bp2;
- bp2 = bp2->b_bufp;
- }
- bp2 = bp2->b_bufp; /* Next one in chain. */
- if (bp1 == NULL) /* Unlink it. */
- bheadp = bp2;
- else
- bp1->b_bufp = bp2;
- free((char *) bp); /* Release buffer block */
- return (TRUE);
- }
-
- namebuffer(f,n) /* Rename the current buffer */
-
- int f, n; /* default Flag & Numeric arg */
-
- {
- register BUFFER *bp; /* pointer to scan through all buffers */
- char bufn[NBUFN]; /* buffer to hold buffer name */
-
- /* prompt for and get the new buffer name */
- ask: if (mlreply("Change buffer name to: ", bufn, NBUFN, QNORML) != TRUE)
- return(FALSE);
-
- /* and check for duplicates */
- bp = bheadp;
- while (bp != NULL) {
- if (bp != curbp) {
- /* if the names the same */
- if (strcmp(bufn, bp->b_bname) == 0)
- goto ask; /* try again */
- }
- bp = bp->b_bufp; /* onward */
- }
-
- strcpy(curbp->b_bname, bufn); /* copy buffer name to structure */
- curwp->w_flag |= WFMODE; /* make mode line replot */
- mlerase();
- }
-
-
-
- itoa(buf, width, num)
- register char buf[];
- register int width;
- register int num;
- {
- buf[width] = 0; /* End of string. */
- while (num >= 10) { /* Conditional digits. */
- buf[--width] = (num%10) + '0';
- num /= 10;
- }
- buf[--width] = num + '0'; /* Always 1 digit. */
- while (width != 0) /* Pad with blanks. */
- buf[--width] = ' ';
- }
-
- /*
- * The argument "text" points to
- * a string. Append this line to the
- * buffer list buffer. Handcraft the EOL
- * on the end. Return TRUE if it worked and
- * FALSE if you ran out of room.
- */
- addline(text)
- char *text;
- {
- register LINE *lp;
- register int i;
- register int ntext;
-
- ntext = strlen(text);
- if ((lp=lalloc(ntext)) == NULL)
- return (FALSE);
- for (i=0; i<ntext; ++i)
- lputc(lp, i, text[i]);
- blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */
- lp->l_bp = blistp->b_linep->l_bp;
- blistp->b_linep->l_bp = lp;
- lp->l_fp = blistp->b_linep;
- if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */
- blistp->b_dotp = lp; /* move it to new line */
- return (TRUE);
- }
-
- /*
- * Look through the list of
- * buffers. Return TRUE if there
- * are any changed buffers. Buffers
- * that hold magic internal stuff are
- * not considered; who cares if the
- * list of buffer names is hacked.
- * Return FALSE if no buffers
- * have been changed.
- */
- anycb()
- {
- register BUFFER *bp;
-
- bp = bheadp;
- while (bp != NULL) {
- if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
- return (TRUE);
- bp = bp->b_bufp;
- }
- return (FALSE);
- }
-
- /*
- * Find a buffer, by name. Return a pointer
- * to the BUFFER structure associated with it. If
- * the named buffer is found, but is a TEMP buffer (like
- * the buffer list) conplain. If the buffer is not found
- * and the "cflag" is TRUE, create it. The "bflag" is
- * the settings for the flags in in buffer.
- */
- BUFFER *
- bfind(bname, cflag, bflag)
- register char *bname;
- {
- register BUFFER *bp;
- register BUFFER *sb; /* buffer to insert after */
- register LINE *lp;
- char *malloc();
-
- bp = bheadp;
- while (bp != NULL) {
- if (strcmp(bname, bp->b_bname) == 0) {
- if ((bp->b_flag&BFTEMP) != 0) {
- mlwrite("Cannot select builtin buffer");
- return (NULL);
- }
- return (bp);
- }
- bp = bp->b_bufp;
- }
- if (cflag != FALSE) {
- if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
- return (NULL);
- if ((lp=lalloc(0)) == NULL) {
- free((char *) bp);
- return (NULL);
- }
- /* find the place in the list to insert this buffer */
- if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
- /* insert at the begining */
- bp->b_bufp = bheadp;
- bheadp = bp;
- } else {
- sb = bheadp;
- while (sb->b_bufp != NULL) {
- if (strcmp(sb->b_bufp->b_bname, bname) > 0)
- break;
- sb = sb->b_bufp;
- }
-
- /* and insert it */
- bp->b_bufp = sb->b_bufp;
- sb->b_bufp = bp;
- }
-
- /* and set up the other buffer fields */
- bp->b_active = TRUE;
- bp->b_dotp = lp;
- bp->b_doto = 0;
- bp->b_markp = NULL;
- bp->b_marko = 0;
- bp->b_flag = bflag;
- bp->b_mode = gmode;
- bp->b_nwnd = 0;
- bp->b_linep = lp;
- strcpy(bp->b_fname, "");
- strcpy(bp->b_bname, bname);
- lp->l_fp = lp;
- lp->l_bp = lp;
- }
- return (bp);
- }
-
- /*
- * This routine blows away all of the text
- * in a buffer. If the buffer is marked as changed
- * then we ask if it is ok to blow it away; this is
- * to save the user the grief of losing text. The
- * window chain is nearly always wrong if this gets
- * called; the caller must arrange for the updates
- * that are required. Return TRUE if everything
- * looks good.
- */
- bclear(bp)
- register BUFFER *bp;
- {
- register LINE *lp;
- register int s = FALSE;
-
- if(Pmaster){
- if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */
- && (bp->b_flag&BFCHG) != 0){ /* Something changed */
- emlwrite("buffer lines not freed.");
- return (s);
- }
- }
- else{
- if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */
- && (bp->b_flag&BFCHG) != 0 /* Something changed */
- && (s=mlyesno("Discard changes", -1)) != TRUE){
- return (s);
- }
- }
-
- bp->b_flag &= ~BFCHG; /* Not changed */
- while ((lp=lforw(bp->b_linep)) != bp->b_linep)
- lfree(lp);
- bp->b_dotp = bp->b_linep; /* Fix "." */
- bp->b_doto = 0;
- bp->b_markp = NULL; /* Invalidate "mark" */
- bp->b_marko = 0;
- return (TRUE);
- }
-
-
- /*
- * packbuf - will pack up the main buffer in the buffer provided
- * to be returned to the program that called pico.
- * if need be, allocate memory for the new message.
- * will also free the memory associated with the editor
- * buffer, by calling zotedit.
- */
- packbuf(buf, blen, lcrlf)
- char **buf;
- int *blen;
- int lcrlf; /* EOLs are local or CRLF */
- {
- register int s;
- register int i = 0;
- register LINE *lp;
- register int nline;
- register int retval = 0;
- register char *bufp;
- register char *eobuf;
-
- if(anycb() != FALSE){
-
- lp = lforw(curbp->b_linep);
- do{ /* how many chars? */
- i += llength(lp);
- /*
- * add extra for new lines to be inserted later
- */
- i += 2;
- lp = lforw(lp);
- }
- while(lp != curbp->b_linep);
-
- if(i > *blen){ /* new buffer ? */
- /*
- * don't forget to add one for the null terminator!!!
- */
- if((bufp = (char *)malloc((i+1)*sizeof(char))) == NULL){
- zotedit(); /* bag it! */
- return(COMP_FAILED);
- }
- free(*buf);
- *buf = bufp;
- *blen = i;
- }
- else{
- bufp = *buf;
- }
-
- eobuf = bufp + *blen;
- lp = lforw(curbp->b_linep); /* First line. */
- nline = 0; /* Number of lines. */
- do {
- for (i = 0; i < llength(lp); i++){ /* copy into buffer */
- if((bufp+1) < eobuf){
- *bufp++ = (lp->l_text[i] & 0xFF);
- }
- else{
- /*
- * the idea is to malloc enough space for the new
- * buffer...
- */
- *bufp = '\0';
- zotedit();
- return(BUF_CHANGED|COMP_FAILED);
- }
- }
- if(lcrlf){
- *bufp++ = '\n'; /* EOLs use local convention */
- }
- else{
- *bufp++ = 0x0D; /* EOLs use net standard */
- *bufp++ = 0x0A;
- }
- ++nline;
- lp = lforw(lp);
- }
- while (lp != curbp->b_linep);
- if(lcrlf)
- *--bufp = '\0';
- else
- *bufp = '\0';
- retval = BUF_CHANGED;
- }
-
- zotedit();
- return(retval);
- }
-
-
- /*
- * readbuf - reads in a buffer.
- */
- readbuf(buf)
- char **buf;
- {
- register LINE *lp1;
- register LINE *lp2;
- register BUFFER *bp;
- register WINDOW *wp;
- register int i;
- register int s;
- register int nline;
- char *sptr; /* pointer into buffer string */
- int nbytes;
- int lflag; /* any lines longer than allowed?*/
- char line[NLINE];
-
- bp = curbp;
- bp->b_flag &= ~(BFTEMP|BFCHG);
- sptr = *buf;
- nline = 0;
- lflag = FALSE;
-
- while ((s=sgetline(&sptr,&nbytes,line,NLINE)) == FIOSUC || s == FIOLNG){
-
- if (s == FIOLNG)
- lflag = TRUE;
-
- if ((lp1=lalloc(nbytes)) == NULL) {
- s = FIOERR; /* Keep message on the */
- break; /* display. */
- }
- lp2 = lback(curbp->b_linep);
- lp2->l_fp = lp1;
- lp1->l_fp = curbp->b_linep;
- lp1->l_bp = lp2;
- curbp->b_linep->l_bp = lp1;
- for (i=0; i<nbytes; ++i)
- lputc(lp1, i, line[i]);
- ++nline;
- }
-
- for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
- if (wp->w_bufp == curbp) {
- wheadp->w_linep = lforw(curbp->b_linep);
- wheadp->w_dotp = lback(curbp->b_linep);
- wheadp->w_doto = 0;
- wheadp->w_markp = NULL;
- wheadp->w_marko = 0;
- wheadp->w_flag |= WFHARD;
- }
- }
-
- strcpy(bp->b_bname, "main");
- strcpy(bp->b_fname, "");
-
- bp->b_dotp = bp->b_linep;
- bp->b_doto = 0;
- }
-
-
- /*
- * sgetline - copy characters from ibuf to obuf, ending at the first
- * newline. return with ibuf pointing to first char after
- * newline.
- */
- sgetline(ibuf, nchars, obuf, blen)
- char **ibuf;
- int *nchars;
- char *obuf;
- int blen;
- {
- register char *len;
- register char *cbuf = *ibuf;
- register char *bufp = obuf;
- register int retval = FIOSUC;
- #define CR '\015'
- #define LF '\012'
-
- *nchars = 0;
- if(*cbuf == '\0'){
- retval = FIOEOF;
- }
- else{
- len = obuf + blen;
- while (*cbuf != CR && *cbuf != LF && *cbuf != '\0'){
- if(bufp < len){
- *bufp++ = *cbuf++;
- (*nchars)++;
- }
- else{
- *bufp = '\0';
- retval = FIOLNG;
- break;
- }
- }
- }
- *bufp = '\0'; /* end retured line */
- *ibuf = (*cbuf == CR) ? ++cbuf : cbuf;
- *ibuf = (*cbuf == LF) ? ++cbuf : cbuf;
- return(retval);
- }
-